﻿using Framework.Core.Io;
using Framework.Core.Process;
using Framework.Core.Process.Tasks;
using Rhino.Mocks;
using Xunit;

namespace Framework.Tests.Core.Io
{
    public class RemoteProcessRunnerTest
    {
        public struct FakeCommand : ICommand
        {
            public int ProcessId { get { return 0; } }
            public string Name { get { return "name"; } }
            public string FileName { get { return "fileName"; } }
            public string Arguments { get { return "args"; } }
            public bool IsNative { get { return false; } }
        }

        private readonly MockRepository mockRepository = new MockRepository();
        private readonly IProcessRunner processRunnerMock;
        private readonly RemoteProcessRunner remoteProcessRunner;
        private const string RemoteMachine = "machine";
        private const string RemoteUser = "usr";
        private const string RemotePassword = "pwd";

        public RemoteProcessRunnerTest()
        {
            processRunnerMock = mockRepository.StrictMock<IProcessRunner>();
            remoteProcessRunner = new RemoteProcessRunner(processRunnerMock, RemoteMachine, RemoteUser, RemotePassword);
        }

        [Fact]
        public void Should_valid_client_construction()
        {
            Assert.NotNull(new RemoteProcessRunner("machine"));
        }

        [Fact]
        public void Should_throw_exception_if_exit_code_of_psexec_is_positive()
        {
            var remoteProcessResultValidator = new RemoteProcessRunner.RemoteProcessResultValidator();

            Assert.False(remoteProcessResultValidator.Validate(new ProcessResult(2250, "stdOut", "errOutput", false)));
        }

        [Fact]
        public void Should_start_process_remotely()
        {
            var cmdProcess = new FakeCommand();

            var expected = new ProcessResult(0, "stdOut", "errOutput", false);

            processRunnerMock
                .Expect(x => x.Start(new PsExec(RemoteMachine, RemoteUser, RemotePassword, cmdProcess)))
                .Return(expected);

            mockRepository.ReplayAll();
            var result = remoteProcessRunner.Start(cmdProcess);
            mockRepository.VerifyAll();

            Assert.Equal(expected, result);
        }

        [Fact]
        public void Should_get_remote_processes()
        {
            mockRepository.ReplayAll();

            mockRepository.VerifyAll();
        }
    }
}